package p3.cse;

import java.io.PrintStream;

/**
 * Storage object for maintaining the representation of the user account
 * information. This includes the object types and how they are printed to
 * files.
 */

public final class Entry implements Comparable<Entry> {
	/**
	 * The human readable account name as it appears to the user.
	 */
	protected String account;

	/**
	 * A fully qualified universal resource locator for which this account is
	 * intended to be used for.
	 */
	protected String url;

	/**
	 * The account-specific identity an entity will use for login purposes.
	 */
	protected String username;

	/**
	 * A secret string of characters the account will use for authentication.
	 */
	protected String password;

	/**
	 * Generates a blank Entry storage object with null fields.
	 */
	public Entry() {
		this.account = null;
		this.url = null;
		this.username = null;
		this.password = null;
	}

	/**
	 * Generates a populated Entry storage object initialized to the provided
	 * fields.
	 * 
	 * @param account
	 *            new user account name
	 * @param url
	 *            new location to use the account
	 * @param username
	 *            new identity for authentication
	 * @param password
	 *            new secret for authentication
	 */
	public Entry(final String account, final String url, final String username,
			final String password) {
		this.account = account;
		this.url = url;
		this.username = username;
		this.password = password;
	}

	/**
	 * Generate a plain-text version of this particular Entry storage.
	 * 
	 * @param out
	 *            an appropriate location for generating the output of this
	 *            Entry
	 */
	public void print(final PrintStream out) {
		out.println(account);
		out.println(url);
		out.println(username);
		out.println(password);
		out.println();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((account == null) ? 0 : account.hashCode());
		result = prime * result
				+ ((password == null) ? 0 : password.hashCode());
		result = prime * result + ((url == null) ? 0 : url.hashCode());
		result = prime * result
				+ ((username == null) ? 0 : username.hashCode());
		return result;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		} else if (obj == null) {
			return false;
		} else if (getClass() != obj.getClass()) {
			return false;
		}
		Entry other = (Entry) obj;
		if (account == null) {
			if (other.account != null) {
				return false;
			}
		} else if (!account.equals(other.account)) {
			return false;
		} else if (password == null) {
			if (other.password != null) {
				return false;
			}
		} else if (!password.equals(other.password)) {
			return false;
		} else if (url == null) {
			if (other.url != null) {
				return false;
			}
		} else if (!url.equals(other.url)) {
			return false;
		} else if (username == null) {
			if (other.username != null) {
				return false;
			}
		} else if (!username.equals(other.username)) {
			return false;
		}
		return true;
	}

	/**
	 * Uses {@code String}'s lexicographic, case-insensitive sort to compare
	 * account names to each other.
	 * 
	 * @param another
	 *            the account to compare to this instance.
	 * @return a negative integer if this account is less than another; a
	 *         positive integer if this account is greater than another; 0 if
	 *         this account has the same order as another.
	 */
	public int compareTo(final Entry another) {
		return this.account.compareToIgnoreCase(another.account);
	}
}
